# You can begin by loading the following packages.
require(readstata13)
require(rdrobust)
require(rdd)
require(ggplot2)
require(cowplot)

# You can next set the working directory to the Data folder. 
setwd("~/PCRD_Replication_Materials/Data")

# Read in the data.
data<-read.dta13("primary_analysis.dta")

# Change the working directory to the Results folder.
setwd("~/PCRD_Replication_Materials/Results")

# Examine the first six rows of the data frame.
head(data)

# We will begin by adding columns to the data frame for 
# the region of the US where the election took place.

south<-c("FL","AL","GA","MS","LA","TX","OK","AK",
         "TN","KY","WV","VA","NC","SC","DE","MD")
northeast<-c("ME","NH","VT","MA","CT","RI","NY",
             "NJ","PA")
midwest<-c("MI","OH","IN","IL","MO","KS","NE","IA",
           "SD","ND","MN","WI")
west<-c("AZ","NM","CA","OR","WA","NV","ID","MT","WY",
        "CO","UT","AK","HI")

data$South<-as.numeric(data$state %in% south)
data$West<-as.numeric(data$state %in% west)
data$Midwest<-as.numeric(data$state %in% midwest)
data$Northeast<-as.numeric(data$state %in% northeast)

# Create a column called dv_dw that represents how much each 
# district's post-election DW-NOMINATE score went in the same  
# direction as (or against) the ideological leaning of the 
# party in that row of the data set. This variable will allow
# us to test whether barely nominating the extremist (rather 
# than the moderate) tended to move the future DW-NOMINATE 
# score for that district in the opposite direction from the 
# party's ideological leaning.

data$dv_dw<-data$dwnom1*(1-2*data$dem)

# We will next predict treatment status for each election
# (i.e. the estimated likelihood of the extremist candidate 
# winning), based on several covariates. As described in the 
# article, the covariates that we use are year, fully open 
# general election, extremist share of money in the primary, 
# and region.

# We first create a logistic regression model to estimate
# the likelihood of the extremist candidate winning each 
# primary election based on the covariates. To reduce the 
# chances of overfitting on the data close to the cut-point,
# we construct this model using the data that is more than 
# 5% away from the cut-point.

model<-glm(treat~year+fully_open_general+
             prim_share+
             Northeast+
             South+
             West,
           data[abs(data$rv)>0.05,],
           family = "binomial")

# We can now estimate the likelihood of the extremist winning
# each primary election.
data$Predicted_T<-predict.glm(model, data, type = "response")

# We will now estimate Y0 and Y1 for each of the three 
# dependent variables: general election vote share, general 
# election victory, and the district's post-election  
# DW-NOMINATE score (in the direction of the party's 
# ideological leaning). By Y0, we mean the predicted value
# of each outcome had the moderate candidate barely won the
# primary, and by Y1 we mean the predicted value of that
# outcome had the extremist candidate barely won the primary.

# We first construct a logistic regression model that can 
# estimate the general election vote share for the party 
# in each row, had that party nominated the moderate
# candidate. To create this model, we use the data where the
# moderate candidate won. Again, to reduce the risk of
# overfitting near the cut-point, we only use the data that
# was at least 5% away from the cut-point.
model<-lm(dv~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West,
          data[abs(data$rv)<=0.05&data$treat==0,])

# We can now estimate the likelihood of the party in each row
# winning the general election had they nominated the moderate.
data$Predicted_VS0<-predict.lm(model, data)

# We repeat this process, but this time estimating the general 
# election vote share for the party in each row had that party 
# nominated the extremist candidate.
model<-lm(dv~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West,
          data[abs(data$rv)<=0.05&data$treat==1,])

data$Predicted_VS1<-predict.lm(model, data)

# We have now estimated the general election vote share for the 
# party in each row had it nominated the moderate candidate (Y0)
# or the extremist candidate (Y1). We can repeat this process
# for the likelihood that the party in each row would win the
# general election.

model<-lm(dv_win~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West,
          data[abs(data$rv)<=0.05&data$treat==0,])

data$Predicted_Win0<-predict.lm(model, data)



model<-lm(dv_win~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West, 
            data[abs(data$rv)<=0.05&data$treat==1,])

data$Predicted_Win1<-predict.lm(model, data)



# We now turn to the district's post-election DW-NOMINATE score.
# We first estimate the DW-NOMINATE score for each district had
# the party nominated the moderate candidate (the Y0 outcome).

model<-lm(dwnom1~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West,
          data[abs(data$rv)<=0.05&data$treat==0,])

data$Predicted_DW0<-predict.lm(model, data)


# We next estimate the district's post-election DW-NOMINATE score
# had the party nominated the extremist candidate (the Y1 outcome).

model<-lm(dwnom1~year+fully_open_general+
            prim_share+
            Northeast+
            South+
            West,
          data[abs(data$rv)<=0.05&
                 data$treat==1,])

data$Predicted_DW1<-predict.lm(model, data)


# We now sign these estimates to be in the same direction
# as the party's ideological leaning.

data$Predicted_DW0_Same_Direction<-data$Predicted_DW0*(1-2*data$dem)

data$Predicted_DW1_Same_Direction<-data$Predicted_DW1*(1-2*data$dem)


# We are now ready to create a truncated data set with just the 
# rows where the ideological distance between the extremist and
# moderate candidate was at or above the median for all rows.

data_truncated<-data[data$absdist>=median(data$absdist),] 

# View the sample size for the full sample.
nrow(data)

# View the range of years in the full sample.
range(data$year)

# View the sample size for the truncated sample.
nrow(data_truncated)

# View the range of years in the truncated sample.
range(data_truncated$year)


# We will begin with the results and figures from the article.
# We will then turn to the results and figures from the online
# appendix.


##########################################################
##### Figure 2: RD Plot with just the dv_win outcome #####
##########################################################

# To create this plot, we will use Andrew Bertoli's RDPlot()
# function. You can load this function with this line of code:

source("https://raw.githubusercontent.com/AndrewBertoli/Natural-Experiments/master/RDPlot_ggplot2.R")

# We can now make the plot.

set.seed(0)

plot_main<-RDPlot(data_truncated$rv, data_truncated$dv_win, 
                  NBoots=10000,Smoother="Local Polynomial", Poly.Order=3,
                  xlab = "Win/Loss Margin of Extremist in Primary",
                  ylab = "Win in General Election",
                  Main = "", Point.Size = 0.5, 
                  Title.Size = 14, ylim = c(0.25,1.3))

# Customize the plot.

plot_main<-plot_main+theme_classic()+
           theme(plot.title = element_text(hjust = 0.5),
           axis.title=element_text(size=13))

# View the plot.
plot_main

# Save the figure.
ggsave("figure2.pdf",scale=2.3,height=1.7,width=3)




##### Results for Win in the General Election #####

# Main Test -- standard 3rd order polynomial
summary(lm(dv_win~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the estimated treatment effect is -0.4507 (meaning 
# about a 45 percentage point drop in the party’s likelihood 
# of winning the general election). The p-value is 0.011 and
# the standard error is 0.1760.





########################################################
############ Figure 3: McCrary Sorting Test ############
########################################################

# We will start by making the plot for the truncated
# sample. We will begin by using the DCdensity() 
# function from the rdd package to calculate the
# bandwidth, x values, and y values for the plot
# for the truncated sample.
output_truncated<-DCdensity(data_truncated$rv,ext.out=T)

# We will use this output to create graphs using ggplot2.
bw<-output_truncated$bw # Save the bandwidth.
cellmp<-output_truncated$data$cellmp # Save the x values.
cellval<-output_truncated$data$cellval # Save the y values.

# Note that the code below follows the code for graphing
# the results inside the DCdensity() function, but
# generates the graph using ggplot2 instead of plot(),
# allowing for additional customizations. The code below
# will also extend the regression lines and confidence
# intervals to 0 on both sides of the cut-point.

# Create a data frame to store the estimates and 
# confidence intervals for different x values.  
left_data <- data.frame(X=cellmp[cellmp < 0], 
             Val=cellval[cellmp < 0], Distance=NA, 
             Estimate=NA, Lower=NA, Upper=NA)

# Use a for loop to calculate the estimates and 
# confidence intervals for each x value.            
for(i in 1:nrow(left_data)){
	left_data$Distance<-left_data$X-left_data[i,"X"]
	kernel_weights<-kernelwts(left_data$Distance, 0, bw, kernel="triangular")
	new_data<-data.frame(Distance=0)
	model<-lm(Val~Distance, left_data, weights=kernel_weights)
	results<-predict(model, interval="confidence", newdata=new_data)
	left_data[i,c("Estimate","Lower","Upper")]<-results}
            
# Since 0 was not an x value, we can calculate the 
# estimate and confidence interval for x=0 separately
# and then store them at the end of the data frame.
zero_left<-data.frame(X=0, Val=NA, Distance=NA, Estimate=NA, 
					  Lower=NA, Upper=NA)
left_data$Distance<-left_data$X-0
kernel_weights<-kernelwts(left_data$Distance, 0, bw, kernel="triangular")
new_data<-data.frame(Distance=0)
model<-lm(Val~Distance, left_data, weights=kernel_weights)
results<-predict(model, interval="confidence", newdata=new_data)
zero_left[c("Estimate","Lower","Upper")]<-results
left_data<-rbind(left_data,zero_left)
        
# We will now repeat this process for the data to the
# right of the cut-point. We will start by creating a 
# data frame to store the estimates and confidence 
# intervals for different x values.        
right_data<-data.frame(X=cellmp[cellmp>0], 
            Val=cellval[cellmp>0], Distance=NA, 
            Estimate=NA, Lower=NA, Upper=NA)

# Use a for loop to calculate the estimates and 
# confidence intervals for each x value.                 
for(i in 1:nrow(right_data)){
	right_data$Distance<-right_data$X-right_data[i,"X"]
	kernel_weights<-kernelwts(right_data$Distance, 0, bw, kernel = "triangular")
	new_data<-data.frame(Distance=0)
	model<-lm(Val~Distance, right_data, weights=kernel_weights)
	results<-predict(model, interval="confidence", newdata=new_data)
	right_data[i,c("Estimate","Lower","Upper")]<-results}

# Since 0 was not an x value, we can calculate the 
# estimate and confidence interval for x=0 separately
# and then store them at the end of the data frame.            
zero_right<-data.frame(X=0, Val=NA, Distance=NA, 
Estimate=NA, Lower= NA, Upper=NA)
right_data$Distance<-right_data$X-0
kernel_weights<-kernelwts(right_data$Distance, 0, bw, kernel="triangular")
new_data<-data.frame(Distance=0)
model<-lm(Val~Distance, right_data, weights=kernel_weights)
results<-predict(model, interval = "confidence", newdata=new_data)
zero_right[c("Estimate","Lower","Upper")]<-results
right_data<-rbind(right_data,zero_right)
        
# We can now make the plot for the truncated data.
MST_truncated<-ggplot()+geom_point(aes(x=cellmp, y=cellval))+
geom_line(aes(x=left_data$X,y=left_data$Estimate))+
geom_line(aes(x=right_data$X,y=right_data$Estimate))+
geom_ribbon(aes(x=left_data$X,
				ymin=left_data$Lower,
				ymax=left_data$Upper),
			colour="gray",alpha=0.2)+
geom_ribbon(aes(x=right_data$X,
				ymin=right_data$Lower,
				ymax=right_data$Upper),
			colour="gray",alpha=0.2)+
geom_vline(xintercept=0)+coord_cartesian(xlim = c(-0.27,0.27), 
										 ylim = c(0,6))+
theme_classic()+										 
theme(axis.text.x=element_text(size=14),
      axis.text.y=element_text(size=14),
      axis.title=element_text(size=14),
      plot.title = element_text(lineheight=1.8,
      size=18,hjust = 0.5))+
xlab("Win/Loss Margin of Extremist in Primary")+
ylab("Density")+ggtitle("Truncated Sample")      

# View the plot.
MST_truncated



# We will now make the plot for the full sample.
# Use the DCdensity() function from the rdd package to 
# calculate the bandwidth, x values, and y values for
# the plot for the full sample.
output_full<-DCdensity(data$rv,ext.out=T)
 
bw_full<-output_full$bw # Save the bandwidth.
cellmp_full<-output_full$data$cellmp # Save the x values.
cellval_full<-output_full$data$cellval # Save the y values.
  
# Create a data frame to store the estimates and 
# confidence intervals for different x values.  
left_data_full <- data.frame(X=cellmp_full[cellmp_full < 0], 
             	  Val=cellval_full[cellmp_full < 0], Distance=NA, 
             	  Estimate=NA, Lower=NA, Upper=NA)

# Use a for loop to calculate the estimates and 
# confidence intervals for each x value.            
for(i in 1:nrow(left_data_full)){
	left_data_full$Distance<-left_data_full$X-left_data_full[i,"X"]
	kernel_weights_full<-kernelwts(left_data_full$Distance, 0, bw, kernel="triangular")
	new_data_full<-data.frame(Distance=0)
	model_full<-lm(Val~Distance, left_data_full, weights=kernel_weights_full)
	results_full<-predict(model_full, interval="confidence", newdata=new_data_full)
	left_data_full[i,c("Estimate","Lower","Upper")]<-results_full}
            
# Since 0 was not an x value, we can calculate the 
# estimate and confidence interval for x=0 separately
# and then store them at the end of the data frame.
zero_left_full<-data.frame(X=0, Val=NA, Distance=NA, Estimate=NA, 
					  	   Lower=NA, Upper=NA)
left_data_full$Distance<-left_data_full$X-0
kernel_weights_full<-kernelwts(left_data_full$Distance, 0, bw, kernel="triangular")
new_data_full<-data.frame(Distance=0)
model_full<-lm(Val~Distance, left_data_full, weights=kernel_weights_full)
results_full<-predict(model_full, interval="confidence", newdata=new_data_full)
zero_left_full[c("Estimate","Lower","Upper")]<-results_full
left_data_full<-rbind(left_data_full,zero_left_full)
        
# We will now repeat this process for the data to the
# right of the cut-point. We will start by creating a 
# data frame to store the estimates and confidence 
# intervals for different x values.        
right_data_full<-data.frame(X=cellmp_full[cellmp_full>0], 
            Val=cellval_full[cellmp_full>0], Distance=NA, 
            Estimate=NA, Lower=NA, Upper=NA)

# Use a for loop to calculate the estimates and 
# confidence intervals for each x value.                 
for(i in 1:nrow(right_data_full)){
	right_data_full$Distance<-right_data_full$X-right_data_full[i,"X"]
	kernel_weights_full<-kernelwts(right_data_full$Distance, 0, bw, kernel = "triangular")
	new_data_full<-data.frame(Distance=0)
	model_full<-lm(Val~Distance, right_data_full, weights=kernel_weights_full)
	results_full<-predict(model_full, interval="confidence", newdata=new_data_full)
	right_data_full[i,c("Estimate","Lower","Upper")]<-results_full}

# Since 0 was not an x value, we can calculate the 
# estimate and confidence interval for x=0 separately
# and then store them at the end of the data frame.            
zero_right_full<-data.frame(X=0, Val=NA, Distance=NA, 
				 Estimate=NA, Lower= NA, Upper=NA)
right_data_full$Distance<-right_data_full$X-0
kernel_weights_full<-kernelwts(right_data_full$Distance, 0, bw, kernel="triangular")
new_data_full<-data.frame(Distance=0)
model_full<-lm(Val~Distance, right_data_full, weights=kernel_weights_full)
results_full<-predict(model_full, interval = "confidence", newdata=new_data_full)
zero_right_full[c("Estimate","Lower","Upper")]<-results_full
right_data_full<-rbind(right_data_full,zero_right_full)
        
# We can now make the plot for the full data.
MST_full<-ggplot()+geom_point(aes(x=cellmp_full, y=cellval_full))+
geom_line(aes(x=left_data_full$X,y=left_data_full$Estimate))+
geom_line(aes(x=right_data_full$X,y=right_data_full$Estimate))+
geom_ribbon(aes(x=left_data_full$X,
				ymin=left_data_full$Lower,
				ymax=left_data_full$Upper),
			colour="gray",alpha=0.2)+
geom_ribbon(aes(x=right_data_full$X,
				ymin=right_data_full$Lower,
				ymax=right_data_full$Upper),
			colour="gray",alpha=0.2)+
geom_vline(xintercept=0)+coord_cartesian(xlim = c(-0.27,0.27), 
										 ylim = c(0,6))+
theme_classic()+
theme(axis.text.x=element_text(size=14),
      axis.text.y=element_text(size=14),
      axis.title=element_text(size=14),
      plot.title = element_text(lineheight=1.8,
      size=18,hjust = 0.5))+
xlab("Win/Loss Margin of Extremist in Primary")+
ylab("Density")+ggtitle("Full Sample")

# View the plot.
MST_full

# Combine the coefficient plots.
plot_grid(MST_truncated, MST_full, ncol=2)

# Save the figure as a PDF.
ggsave("figure3a.pdf", height=3.5, width=9)



# To view the p-value for the truncated data, we can
# use the DCdensity() function.

DCdensity(data_truncated$rv, plot=F)

# Note that the p-value is about 0.96.

# To view the p-value for the full sample, we can
# again use the DCdensity() function.

DCdensity(data$rv, plot=F)

# Note that the p-value is about 0.44.




# Calculate the estimates and standard errors 
# for the differences at the cut-point.

# The truncated dataset
out1<-DCdensity(data_truncated$rv,ext.out=T, plot=F)
est1<-out1$theta
se1<-out1$se

# The full dataset
out2<-DCdensity(data$rv,ext.out=T, plot=F)
est2<-out2$theta
se2<-out2$se

# Store the estimate, standard error, and 90% and
# 95% confidence intervals for the truncated dataset.
MST1<-c(est1, se1, est1+1.96*se1, 
        est1-1.96*se1, 
        est1+1.65*se1, 
        est1-1.65*se1)

# Store the estimate, standard error, and 90% and
# 95% confidence intervals for the full sample.
MST2<-c(est2, se2, est2+1.96*se2, 
        est2-1.96*se2, 
        est2+1.65*se2, 
        est2-1.65*se2)

# Create an empty data frame to store the estimates
# and confidence intervals.
cd <- as.data.frame(matrix(NA,2,6))

# Name the columns.
names(cd) <- c("mean","lower95","upper95",
               "lower90","upper90","measure")

# Store the means.
cd$mean <- c(MST1[1],MST2[1])

# Store the lower bounds of the 95% confidence intervals.
cd$lower95 <- c(MST1[4],MST2[4])

# Store the upper bounds of the 95% confidence intervals.
cd$upper95 <- c(MST1[3],MST2[3])

# Store the lower bounds of the 90% confidence intervals.
cd$lower90 <- c(MST1[6],MST2[6])

# Store the upper bounds of the 90% confidence intervals.
cd$upper90 <- c(MST1[5],MST2[5])

# Add a column with the names of the two samples.
cd$measure <- c("Truncated Sample","Full Sample")


# Make the plot.

plot1 <- ggplot(cd, 
                aes(x=mean,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  geom_errorbarh(aes(xmax =  upper95, 
                     xmin = lower95),
                 linewidth=0.75, height=0,color="blue")+
  geom_errorbarh(aes(xmax =  upper90, 
                     xmin = lower90),
                 linewidth=1.5, height=0,color="blue")  +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference at Cut-point")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=7.4),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=rel(1.5),
                                  face="bold"))+
  theme_classic() + xlim(c(-1,1))

# View the plot.

plot1

# Save the plot as a PDF file.

ggsave("figure3b.pdf",scale=1.3,height=0.8,width=4.4)



#########################################################
##### Figure 4: Shorter balance plots for the paper #####
#########################################################

# Make a vector with the covariates.
covariates<-c("year",
              "fully_open_general",
              "abs_dw_lag",
              "abs_lag_wnom",
              "competitive",
              "Northeast",
              "South",
              "Midwest",
              "West",
              "prim_share",
              "prim_pac_share",
              "prim_total0", # Extremist Total Primary Money (100k)
              "dv_lag", 
              "Predicted_T",
              "Predicted_Win0",
              "Predicted_Win1")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  output<-summary(lm(data_truncated[,covariates[i]]~data_truncated$treat+
                     data_truncated$rv+data_truncated$rv2+
                     data_truncated$rv3+I(data_truncated$treat*data_truncated$rv)+
                     I(data_truncated$treat*data_truncated$rv2)+
                     I(data_truncated$treat*data_truncated$rv3)))$coefficients
 
  sd_cov<-sd(data_truncated[abs(data_truncated$rv)<=0.5,covariates[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Win Probability of Moderate in General (Predicted Y0)",
                "Predicted Win Probability of Extremist in General (Predicted Y1)"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Store colors for each covariate.
cs<-c("blue","blue","blue","blue","blue",
      "blue","blue","blue","blue","blue",
      "blue","blue","blue",  "red",
      "cornflowerblue","cornflowerblue")

# Make the plot.

plot3 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
         geom_vline(xintercept=0, linetype="longdash")+
         theme_classic()+
         geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                        linewidth=0.75, height=0,color=cs) +
         geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                        linewidth=1.5, height=0,color=cs) +             
         geom_point(stat="identity",size=4,fill="white",color=cs)+
         xlab("Estimated Difference (Standardized)")+ylab("") +  
         theme(legend.position="none",
               axis.text.x=element_text(size=8.2),
               axis.text.y=element_text(size=9.5),
               axis.title=element_text(size=10),
               plot.title = element_text(lineheight=1.8,
                                         size=18,hjust = 0.5))+  
               scale_x_continuous(limits=c(-2.5,2.5),
                                  breaks=c(-1.2,-0.8,-0.5,-0.2,
                                           0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Truncated Sample")

# View the plot.
plot3


# We will now make the coefficient plot for the full sample. We begin
# by creating a data frame to store the estimates, standard deviations,
# and confidence intervals for the full sample.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  output<-summary(lm(data[,covariates[i]]~data$treat+
                       data$rv+data$rv2+
                       data$rv3+I(data$treat*data$rv)+
                       I(data$treat*data$rv2)+
                       I(data$treat*data$rv3)))$coefficients
  
  sd_cov<-sd(data[abs(data$rv)<=0.5,covariates[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Win Probability of Moderate in General (Predicted Y0)",
                "Predicted Win Probability of Extremist in General (Predicted Y1)"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot4 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color=cs) +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color=cs) +             
  geom_point(stat="identity",size=4,fill="white",color=cs)+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.5,2.5),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Full Sample")

# View the plot.
plot4

# Combine the coefficient plots.
plot_grid(plot3,plot4,ncol=1)

# Save the resulting figure as a PDF.
ggsave("figure4.pdf",scale=2.1,height=4.2,width=4.05)


# Balance on Northeast in the truncated sample

summary(lm(Northeast~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the p-value is 0.004.

# Balance on Northeast in the full sample

summary(lm(Northeast~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data))

# Note that the p-value is 0.159.



# Balance on predicted treatment in the truncated sample

summary(lm(Predicted_T~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the p-value is 0.490.

# Balance on predicted treatment in the full sample

summary(lm(Predicted_T~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data))

# Note that the p-value is 0.190.


# Balance on estimated win probability for moderate candidates
# in the truncated sample

summary(lm(Predicted_Win0~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the p-value is not statistically significant (p=0.235).



# Balance on estimated win probability for extremist candidates
# in the truncated sample

summary(lm(Predicted_Win1~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the p-value is not statistically significant (p=0.444).





################################################
##### Figure 5: Plots comparing extremist  #####
##### bare winners to moderate bare winners ####
################################################

# Make a vector with the leader traits.
leader_traits<-c("winner_female","dem",
                 "inc_winner","prim_total_winner")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(leader_traits),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each leader trait.
for(i in 1:length(leader_traits)){
  
  output<-summary(lm(data_truncated[,leader_traits[i]]~data_truncated$treat+
                       data_truncated$rv+data_truncated$rv2+
                       data_truncated$rv3+I(data_truncated$treat*data_truncated$rv)+
                       I(data_truncated$treat*data_truncated$rv2)+
                       I(data_truncated$treat*data_truncated$rv3)))$coefficients
  
  sd_cov<-sd(data_truncated[abs(data_truncated$rv)<=0.5,leader_traits[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-leader_traits

# Create a column of names for the leader traits.
cd$measure <- c("Female","Democrat",
                "Incumbent","Total Money in Primary")

# Set the order of the leader traits in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot6 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=14,hjust = 0.5))+  
  scale_x_continuous(limits=c(-1.4,1.4),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Truncated Sample")

# View the coefficient plot.
plot6


# We will now make the coefficient plot for the full sample. We begin
# by creating a data frame to store the estimates, standard deviations,
# and confidence intervals for the full sample.
cd<-as.data.frame(matrix(0,nrow=length(leader_traits),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each leader trait.
for(i in 1:length(leader_traits)){
  
  output<-summary(lm(data[,leader_traits[i]]~data$treat+
                     data$rv+data$rv2+
                     data$rv3+I(data$treat*data$rv)+
                     I(data$treat*data$rv2)+
                     I(data$treat*data$rv3)))$coefficients
  
  sd_cov<-sd(data[abs(data$rv)<=0.5,leader_traits[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-leader_traits

# Create a column of names for the leader traits.
cd$measure <- c("Female","Democrat",
                "Incumbent","Total Money in Primary")

# Set the order of the leader traits in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot7 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=14,hjust = 0.5))+  
  scale_x_continuous(limits=c(-1.4,1.4),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Full Sample")

# View the coefficient plot.
plot7

# Combine the coefficient plots.
plot_grid(plot6,plot7,ncol=1)

# Save the resulting figure as a PDF.
ggsave("figure5.pdf",scale=1.5,height=2.1,width=4)




# Balance on incumbent status in the truncated sample

summary(lm(inc_winner~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data_truncated))

# Note that the p-value is 0.234.



# Balance on incumbent status in the full sample

summary(lm(inc_winner~treat+rv+rv2+rv3+I(treat*rv)+
             I(treat*rv2)+I(treat*rv3),
           data))

# Note that the p-value is 0.0627.



##########################################################
##########################################################
############ Results from the online appendix ############
##########################################################
##########################################################

##########################################################
##### Figure A2: RD plot with the RDPlot() function ######
##### and the corresponding coefficient plots       ######
##########################################################

set.seed(0)

# Create the RD plot for vote share in the general election.
plot1<-RDPlot(data_truncated$rv, data_truncated$dv, NBoots=10000,
              Smoother="Local Polynomial", Poly.Order=3,
              xlab = "Win/Loss Margin of Extremist in Primary",
              ylab = "Vote Share in General Election",
              Main = "Vote Share in General Election",
              Point.Size = 0.5, ylim = c(0.4,0.8))
              


# Customize the plot.
plot1<-plot1+theme_classic()+
  theme(axis.text=element_text(size=11),
        axis.title=element_text(size=14),
        plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# Create the RD plot for victory in the general election.
plot2<-RDPlot(data_truncated$rv, data_truncated$dv_win, NBoots=10000,
              Smoother="Local Polynomial", Poly.Order=3,
              xlab = "Win/Loss Margin of Extremist in Primary",
              ylab = "Win in General Election",
              Main = "Win in General Election",
              Point.Size = 0.5, ylim = c(0.25,1.3))


# Customize the plot.
plot2<-plot2+theme_classic()+
  theme(axis.text=element_text(size=11),
        axis.title=element_text(size=14),
        plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# Create the RD plot for the DW-NOMINATE outcome.
plot3<-RDPlot(data_truncated$rv, data_truncated$dv_dw, NBoots=10000,
              Smoother="Local Polynomial", Poly.Order=3,
              xlab = "Win/Loss Margin of Extremist in Primary",
              ylab = "DW-NOMINATE in Subsequent Term\n(in Ideological Direction of Party)",
              Main = "DW-NOMINATE Outcome",
              Point.Size = 0.5, ylim = c(-0.35,0.65))


# Customize the plot.
plot3<-plot3+theme_classic()+
  theme(axis.text=element_text(size=11),
        axis.title=element_text(size=14),
        plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# Combine the plots into one figure.
plot_grid(plot1,plot2,plot3,ncol=3)

# Save the resulting figure as a PDF.
ggsave("figureA2a.pdf",scale=3,height=1.5,width=4.4)



##### Coefficient plot with the results for all three outcomes #####

# Make a vector with the outcomes.
outcomes<-c("dv","dv_win","dv_dw")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(outcomes),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each outcome.
for(i in 1:length(outcomes)){
  
  output<-summary(lm(data_truncated[,outcomes[i]]~data_truncated$treat+
                       data_truncated$rv+data_truncated$rv2+
                       data_truncated$rv3+I(data_truncated$treat*data_truncated$rv)+
                       I(data_truncated$treat*data_truncated$rv2)+
                       I(data_truncated$treat*data_truncated$rv3)))$coefficients
  
  sd_cov<-sd(data_truncated[abs(data_truncated$rv)<=0.5,outcomes[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-outcomes

# Create a column of names for the three outcomes.
cd$measure <- c("Vote Share in General Election",
                "Win in General Election",
                "DW-NOMINATE in Subsequent Term (in Ideological Direction of Party)")

# Set the order of the outcomes in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot4 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=7),
        axis.text.y=element_text(size=7),
        axis.title=element_text(size=10))+  
  scale_x_continuous(limits=c(-2.2,2.2),
                     breaks=c(-1.2,-1,-0.8,-0.5,-0.2,0,
                              0.2,0.5,0.8,1,1.2),
                     labels=c("-1.2\nvery large","-1",
                              "-0.8\nlarge","-0.5\nmed",
                              "-0.2\nsmall","0","0.2\nsmall",
                              "0.5\nmed","0.8\nlarge","1",
                              "1.2\nvery large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) 

# View the coefficient plot.
plot4

# Save the figure as a PDF.
ggsave("figureA2b.pdf",scale=1.8,height=0.8,width=4.4)






####################################################################
##### Figure A3: Longer balance plots for the online appendix ######
####################################################################

# Make a vector with the covariates.
covariates<-c("year",
              "fully_open_general",
              "abs_dw_lag",
              "abs_lag_wnom",
              "competitive",
              "Northeast",
              "South",
              "Midwest",
              "West",
              "prim_share",
              "prim_pac_share",
              "prim_total0", # Extremist Total Primary Money (100k)
              "dv_lag", 
              "Predicted_T",
              "Predicted_VS0",
              "Predicted_VS1",
              "Predicted_Win0",
              "Predicted_Win1",
              "Predicted_DW0_Same_Direction",
              "Predicted_DW1_Same_Direction")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  output<-summary(lm(data_truncated[,covariates[i]]~data_truncated$treat+
                       data_truncated$rv+data_truncated$rv2+
                       data_truncated$rv3+I(data_truncated$treat*data_truncated$rv)+
                       I(data_truncated$treat*data_truncated$rv2)+
                       I(data_truncated$treat*data_truncated$rv3)))$coefficients
  
  sd_cov<-sd(data_truncated[abs(data_truncated$rv)<=0.5,covariates[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Vote Share of Moderate in General",
                "Predicted Vote Share of Extremist in General",
                "Predicted Win Probability of Moderate in General",
                "Predicted Win Probability of Extremist in General",
                "Predicted DW-NOMINATE Outcome After Moderate Win",
                "Predicted DW-NOMINATE Outcome After Extremist Win"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Store colors for each covariate.
cs<-c("blue","blue","blue","blue","blue",
      "blue","blue","blue","blue","blue",
      "blue","blue","blue",
      "red",
      "cornflowerblue","cornflowerblue",
      "cornflowerblue","cornflowerblue",
      "cornflowerblue","cornflowerblue")

# Make the plot.

plot5 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color=cs) +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color=cs) +             
  geom_point(stat="identity",size=4,fill="white",color=cs)+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.5,2.5),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Truncated Sample")

# View the plot.
plot5



# We will now make the coefficient plot for the full sample. We begin
# by creating a data frame to store the estimates, standard deviations,
# and confidence intervals for the full sample.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  output<-summary(lm(data[,covariates[i]]~data$treat+
                       data$rv+data$rv2+
                       data$rv3+I(data$treat*data$rv)+
                       I(data$treat*data$rv2)+
                       I(data$treat*data$rv3)))$coefficients
  
  sd_cov<-sd(data[abs(data$rv)<=0.5,covariates[i]],na.rm=T)
  
  results<-output[2,]
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Vote Share of Moderate in General",
                "Predicted Vote Share of Extremist in General",
                "Predicted Win Probability of Moderate in General",
                "Predicted Win Probability of Extremist in General",
                "Predicted DW-NOMINATE Outcome After Moderate Win",
                "Predicted DW-NOMINATE Outcome After Extremist Win"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot6 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color=cs) +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color=cs) +             
  geom_point(stat="identity",size=4,fill="white",color=cs)+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.5,2.5),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Full Sample")

# View the plot.
plot6

# Combine the coefficient plots.
plot_grid(plot5,plot6,ncol=1)

# Save the resulting figure as a PDF.
ggsave("figureA3.pdf",scale=2,height=4.2,width=4.05)








#####################################################################
##### Figure A4: Plots shifting the minimum ideology difference #####
#####################################################################

# We will begin with the vote share outcome. Create a vector with 
# the ideological difference thresholds.
min_ig<-seq(0,0.30,by=0.02)

# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Create a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  output<-summary(lm(dv~treat+
                      rv+rv2+
                      rv3+I(treat*rv)+
                      I(treat*rv2)+
                      I(treat*rv3),dat))$coefficients
  st_dv<-sd(data$dv,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column.
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
shift<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs)+ # Start the ggplot, specify the 
                                                         # data frame, set x as the  
                                                         # estimates and y as the labels, 
                                                         # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs)+ # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash")+ # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs)+ 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs)+ 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)")+ 
  ylab("")+ # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5))+ 
  xlim(-4,4)  + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Vote Share in General Election") # Add a plot title.

# View the plot.
shift




# We will now make the plot for the victory in general election outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Create a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  output<-summary(lm(dv_win~treat+
                      rv+rv2+
                      rv3+I(treat*rv)+
                      I(treat*rv2)+
                      I(treat*rv3),dat))$coefficients
  st_dv<-sd(data$dv_win,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column. 
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
shift2<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs)+ # Start the ggplot, specify the 
                                                          # data frame, set x as the  
                                                          # estimates and y as the labels, 
                                                          # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs)+ # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash")+ # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs)+ 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs)+ 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)")+ 
  ylab("")+ # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5))+ 
  xlim(-4,4)  + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Victory in General Election") # Add a plot title.

# Print the plot.
shift2





# We will now make the plot for the DW-NOMINATE outcome. Create a matrix
# to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Create a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  output<-summary(lm(dv_dw~treat+
                      rv+rv2+
                      rv3+I(treat*rv)+
                      I(treat*rv2)+
                      I(treat*rv3),dat))$coefficients
  st_dv<-sd(data$dv_dw,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column.
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
shift3<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs)+ # Start the ggplot, specify the 
                                                          # data frame, set x as the  
                                                          # estimates and y as the labels, 
                                                          # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs)+ # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash")+ # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs)+ 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs)+ 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)")+ 
  ylab("Minimum Gap in Estimated Ideological Distance")+ # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5))+ 
  xlim(-4,4)  + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("DW-NOMINATE in Subsequent Term (in Ideological Direction of Party)") # Add a plot title.

# Print the plot.
shift3

# Customize the plots.
shift<-shift+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
shift2<-shift2+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
shift3<-shift3+theme_classic()+theme(plot.title = element_text(hjust = 0.5))

# Combine the three plots into one figure.
plot_grid(shift, shift2, shift3, ncol=1)

# Save the figure as a PDF.
ggsave("figureA4.pdf",height=5,width=5,scale=1.5)







###################################################################
##### Figure A5: Bandwidth plots with local linear regression #####
###################################################################

# We will begin with the vote share outcome. Create a vector of bandwidths.
bw<-seq(0.02,0.30,by=0.01)

# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases in the bandwidth.
  dat<-data_truncated[abs(data_truncated$rv)<=bw[i],]	
  
  output<-summary(lm(dv~treat+
                      rv+I(treat*rv),
                    dat))$coefficients
  st_dv<-sd(data_truncated$dv,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column. 
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
bandwidth1<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)") + 
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-3.5,3.5) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Vote Share in General Election") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the figure.
bandwidth1




# We will now make the plot for the victory in general election outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes. 
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases in the bandwidth.
  dat<-data_truncated[abs(data_truncated$rv)<=bw[i],]	
  
  output<-summary(lm(dv_win~treat+
                      rv+I(treat*rv),
                    dat))$coefficients
  st_dv<-sd(data_truncated$dv_win,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column.
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
bandwidth2<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)") + 
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-3.5,3.5) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Victory in General Election") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the figure.
bandwidth2





# We will now make the plot for the DW-NOMINATE outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases in the bandwidth.
  dat<-data_truncated[abs(data_truncated$rv)<=bw[i],]	
  
  output<-summary(lm(dv_dw~treat+
                      rv+I(treat*rv),
                    dat))$coefficients
  st_dv<-sd(data_truncated$dv_dw,na.rm=T)
  results<-output[2,]
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column.
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
bandwidth3<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)") + 
  ylab("Bandwidth") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-3.5,3.5) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("DW-NOMINATE in Subsequent Term (in Ideological Direction of Party)") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the plot.
bandwidth3

# Customize the plots.
bandwidth1<-bandwidth1+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
bandwidth2<-bandwidth2+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
bandwidth3<-bandwidth3+theme_classic()+theme(plot.title = element_text(hjust = 0.5))

# Combine the three plots into a single figure.
plot_grid(bandwidth1,bandwidth2,bandwidth3,ncol=1)

# Save the figure as a PDF.
ggsave("figureA5.pdf",height=5,width=5,scale=1.5)










################################################
##### Figure A6: RD graphs and coefficient ##### 
##### plots with the rdrobust software     #####
################################################

# Plot for vote share in the general election
plot1<-rdplot(data_truncated$dv,data_truncated$rv,
              title = "Vote Share in General Election",
              y.label = "Vote Share in General Election",
              x.label = "Win/Loss Margin of Extremist in Primary")$rdplot+
              theme(axis.text=element_text(size=14),
              		axis.title=element_text(size=14),
              		plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# View the plot.
plot1

# Plot for victory in the general election
plot2<-rdplot(data_truncated$dv_win,data_truncated$rv,
              title = "Win in General Election",
              y.label = "Win in General Election",
              x.label = "Win/Loss Margin of Extremist in Primary")$rdplot+
              theme(axis.text=element_text(size=14),
              		axis.title=element_text(size=14),
              		plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# View the plot.
plot2

# Plot for the DW-Nominate outcome
plot3<-rdplot(data_truncated$dv_dw,data_truncated$rv,
              title = "DW-NOMINATE Outcome",
              y.label = "DW-NOMINATE in Subsequent Term\n(in Ideological Direction of Party)",
              x.label = "Win/Loss Margin of Extremist in Primary")$rdplot+
              theme(axis.text=element_text(size=14),
              		axis.title=element_text(size=14),
              		plot.title = element_text(lineheight=1.8, size= 17, hjust = 0.5))

# View the plot.
plot3

# Combine the three plots into one figure.
plot_grid(plot1, plot2, plot3, ncol=3)

# Save the resulting figure as a PDF.
ggsave("figureA6a.pdf",scale=3,height=1.5,width=4.4)




##### Coefficient plots with the rdrobust software #####

# Create a vector with the three outcomes.
outcomes<-c("dv","dv_win","dv_dw")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-matrix(0, nrow=length(outcomes), ncol=7)

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each outcome.
for(i in 1:length(outcomes)){
  
  est<-rdrobust(data_truncated[,outcomes[i]],data_truncated$rv)[[3]][3]
  se<-rdrobust(data_truncated[,outcomes[i]],data_truncated$rv)[[4]][3]
  st_dv<-sd(data_truncated[,outcomes[i]],na.rm=T)
  results<-c(est,se)
  cd[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
            (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
            (results[1]-1.65*results[2])/st_dv)
  
}


# Name the columns of the matrix.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the matrix.
rownames(cd)<-outcomes

# Convert cd into a data frame.
cd<-data.frame(cd)

# Create a column of names for the three outcomes.
cd$measure <- c("Vote Share in General Election",
                "Win in General Election",
                "DW-NOMINATE in Subsequent Term\n(in Ideological Direction of Party)")

# Set the order of the outcomes in the figure.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot7 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=7),
        axis.text.y=element_text(size=7),
        axis.title=element_text(size=10))+  
  scale_x_continuous(limits=c(-2.6,2.6),
                     breaks=c(-1.2,-1,-0.8,-0.5,-0.2,0,
                              0.2,0.5,0.8,1,1.2),
                     labels=c("-1.2\nvery large","-1",
                              "-0.8\nlarge","-0.5\nmed",
                              "-0.2\nsmall","0","0.2\nsmall",
                              "0.5\nmed","0.8\nlarge","1",
                              "1.2\nvery large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) 

# View the coefficient plot.
plot7

# Save the figure as a PDF.
ggsave("figureA6b.pdf",scale=1.8,height=0.8,width=4.4)














###################################################
##### Figure A7: Balance plots with rdrobust ######
###################################################

# Make a vector with the covariates.
covariates<-c("year",
              "fully_open_general",
              "abs_dw_lag",
              "abs_lag_wnom",
              "competitive",
              "Northeast",
              "South",
              "Midwest",
              "West",
              "prim_share",
              "prim_pac_share",
              "prim_total0", # Extremist Total Primary Money (100k)
              "dv_lag", 
              "Predicted_T",
              "Predicted_VS0",
              "Predicted_VS1",
              "Predicted_Win0",
              "Predicted_Win1",
              "Predicted_DW0_Same_Direction",
              "Predicted_DW1_Same_Direction")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  est<-rdrobust(data_truncated[,covariates[i]],data_truncated$rv)[[3]][3]
  se<-rdrobust(data_truncated[,covariates[i]],data_truncated$rv)[[4]][3]
  st_dv<-sd(data_truncated[,covariates[i]],na.rm=T)
  results<-c(est,se)
  cd[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
                              (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
                              (results[1]-1.65*results[2])/st_dv)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Vote Share of Moderate in General",
                "Predicted Vote Share of Extremist in General",
                "Predicted Win Probability of Moderate in General",
                "Predicted Win Probability of Extremist in General",
                "Predicted DW-NOMINATE Outcome After Moderate Win",
                "Predicted DW-NOMINATE Outcome After Extremist Win"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Store colors for each covariate.
cs<-c("blue","blue","blue","blue","blue",
      "blue","blue","blue","blue","blue",
      "blue","blue","blue",
      "red",
      "cornflowerblue","cornflowerblue",
      "cornflowerblue","cornflowerblue",
      "cornflowerblue","cornflowerblue")

# Make the plot.

plot8 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color=cs) +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color=cs) +             
  geom_point(stat="identity",size=4,fill="white",color=cs)+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.5,2.5),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Truncated Sample")

# View the plot.
plot8



# We will now make the coefficient plot for the full sample. We begin
# by creating a data frame to store the estimates, standard deviations,
# and confidence intervals for the full sample.
cd<-as.data.frame(matrix(0,nrow=length(covariates),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each covariate.
for(i in 1:length(covariates)){
  
  est<-rdrobust(data[,covariates[i]],data$rv)[[3]][3]
  se<-rdrobust(data[,covariates[i]],data$rv)[[4]][3]
  st_dv<-sd(data[,covariates[i]],na.rm=T)
  results<-c(est,se)
  cd[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
            (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
            (results[1]-1.65*results[2])/st_dv)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-covariates

# Create a column of names for the covariates.
cd$measure <- c("Year","Fully Open Election",
                "Lagged DW-NOMINATE",
                "Lagged W-NOMINATE",
                "Competitive",
                "Northeast",
                "South",
                "Midwest",
                "West",
                "Extremist Share of Money in Primary",
                "Extremist Share of Primary PAC Money",
                "Extremist Total Primary Money",
                "Lagged Vote Share",
                "Predicted Extremist Primary Win (Predicted T)",
                "Predicted Vote Share of Moderate in General",
                "Predicted Vote Share of Extremist in General",
                "Predicted Win Probability of Moderate in General",
                "Predicted Win Probability of Extremist in General",
                "Predicted DW-NOMINATE Outcome After Moderate Win",
                "Predicted DW-NOMINATE Outcome After Extremist Win"
)

# Set the order of the covariates in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot9 <- ggplot(cd, aes(x=st_estimate,y=measure,color=cs))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color=cs) +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color=cs) +             
  geom_point(stat="identity",size=4,fill="white",color=cs)+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.5,2.5),
                     breaks=c(-1.2,-0.8,-0.5,-0.2,
                              0.2,0.5,0.8,1.2),
                     labels=c("-1.2\nvery large         ",
                              "-0.8\nlarge   ","-0.5\nmed ",
                              "-0.2\n small","0.2\nsmall ",
                              "0.5\n med","0.8\n   large",
                              "1.2\n         very large")) +  
  geom_vline(xintercept=c(-1.2,-0.8,-0.5,-0.2,0.2,0.5,0.8,1.2),
             linetype=rep("dashed",8),
             colour=c("blue","royalblue","cornflowerblue","lightblue",
                      "lightpink","palevioletred1","firebrick2",
                      "firebrick")) + 
  ggtitle("Full Sample")

# View the plot.
plot9

# Combine the coefficient plots.
plot_grid(plot8,plot9,ncol=1)

# Save the figure as a PDF.
ggsave("figureA7.pdf",scale=2,height=4.2,width=4.05)












##################################################
##### Figure A8: Graphs shifting the minimum #####
##### ideology difference with rdrobust      #####
##################################################

# We will begin with the vote share outcome. Create a vector with 
# the ideology difference thresholds.
min_ig<-seq(0,0.30,by=0.02)

# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Create a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  es<-rdrobust(dat$dv,dat$rv)[[3]][3]
  se<-rdrobust(dat$dv,dat$rv)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data$dv,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column.
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
shift4<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)") + 
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-2.65,2.65) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Vote Share in General Election") # Add a plot title.

# View the plot.
shift4



# We will now make the plot for the victory in general election outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  es<-rdrobust(dat$dv_win,dat$rv)[[3]][3]
  se<-rdrobust(dat$dv_win,dat$rv)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data$dv_win,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column. 
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
shift5<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  # Set the x-axis title.
  xlab("Estimated Effect\n(standardized)") + 
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-4.2,4.2) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Victory in General Election") # Add a plot title.

# View the plot.
shift5





# We will now make the plot for the DW-NOMINATE outcome. Create a matrix
# to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(min_ig),ncol=7)

# Create a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){
  # Subset to the cases that meet the minimum-ideology-difference requirement.
  dat<-data[abs(data$absdist)>=min_ig[i],]	
  
  es<-rdrobust(dat$dv_dw,dat$rv)[[3]][3]
  se<-rdrobust(dat$dv_dw,dat$rv)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data$dv_dw,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the minimum ideological gaps to the data frame est as a column.
est$min_ig<-min_ig

# Put the labels into an order so they can be plotted.
est$min_ig <- factor(est$min_ig, levels=est$min_ig)

# Create colors so that they go from lighter to darker as
# the minimum ideology difference increases.
cs<-scales::seq_gradient_pal("cornflowerblue", "blue3", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
shift6<-ggplot(est,aes(x=st_estimate,y=min_ig),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  xlab("Estimated Effect\n(standardized)") + # Set the x-axis title.
  ylab("Minimum Gap in Estimated Ideological Distance") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-4.2,4.2) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("DW-NOMINATE in Subsequent Term (in Ideological Direction of Party)") # Add a plot title.

# View the plot.
shift6

# Customize the plots.
shift4<-shift4+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
shift5<-shift5+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
shift6<-shift6+theme_classic()+theme(plot.title = element_text(hjust = 0.5))

# Combine the three plots into one figure.
plot_grid(shift4, shift5, shift6, ncol=1)

# Save the figure as a PDF.
ggsave("figureA8.pdf",height=5,width=5,scale=1.5)






#####################################################
##### Figure A9: Bandwidth graphs with rdrobust #####
#####################################################

# We will begin with the vote share outcome. Create a vector of bandwidths.
bw<-seq(0.02,0.30,by=0.01)

# Create a matrix to store the estimates, confidence intervals, and sample sizes. 
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){

  es<-rdrobust(data_truncated$dv,data_truncated$rv,h=bw[i],p=1)[[3]][3]
  se<-rdrobust(data_truncated$dv,data_truncated$rv,h=bw[i],p=1)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data_truncated$dv,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
            (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
            (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column.
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
bandwidth4<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  xlab("Estimated Effect\n(standardized)") + # Set the x-axis title.
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-2,2) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Vote Share in General Election") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the plot
bandwidth4




# We will now make the plot for the victory in general election outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes. 
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){

  es<-rdrobust(data_truncated$dv_win,data_truncated$rv,h=bw[i],p=1)[[3]][3]
  se<-rdrobust(data_truncated$dv_win,data_truncated$rv,h=bw[i],p=1)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data_truncated$dv_win,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column. 
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations. 
bandwidth5<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash") + # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  xlab("Estimated Effect\n(standardized)") + # Set the x-axis title. 
  ylab("") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-3.7,3.7) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("Victory in General Election") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the plot.
bandwidth5





# We will now make the plot for the DW-NOMINATE outcome.
# Create a matrix to store the estimates, confidence intervals, and sample sizes.
est<-matrix(0,nrow=length(bw),ncol=7)

# Use a for loop to store the estimates and confidence intervals in est.
for(i in 1:nrow(est)){

  es<-rdrobust(data_truncated$dv_dw,data_truncated$rv,h=bw[i],p=1)[[3]][3]
  se<-rdrobust(data_truncated$dv_dw,data_truncated$rv,h=bw[i],p=1)[[4]][3]
  results<-c(es,se)
  st_dv<-sd(data_truncated$dv_dw,na.rm=T)
  est[i,]<-c(results[1], st_dv,results[1]/st_dv, (results[1]+1.96*results[2])/st_dv, 
             (results[1]-1.96*results[2])/st_dv, (results[1]+1.65*results[2])/st_dv, 
             (results[1]-1.65*results[2])/st_dv)
  
}

# Turn est into a data frame.
est<-data.frame(est)

# Set the column names for est.
colnames(est)<-c("estimate",
                 "se",
                 "st_estimate",
                 "upper95", 
                 "lower95",
                 "upper90", 
                 "lower90")

# Add the bandwidths to the data frame est as a column.
est$bw<-bw

# Create colors so that they go from darker to lighter as the bandwidth increases.
cs<-scales::seq_gradient_pal("blue3", "cornflowerblue", "Lab")(seq(0,1,length.out=nrow(est)))

# Make the ggplot with the desired customizations.
bandwidth6<-ggplot(est,aes(x=st_estimate,y=bw),color=cs) + # Start the ggplot, specify the 
                                                           # data frame, set x as the  
                                                           # estimates and y as the labels, 
                                                           # and set the colors.
  geom_point(stat="identity",size=4,fill="white",color=cs) + # Plot the estimates as points.
  geom_vline(xintercept=0,linetype="longdash")+ # Draw a vertical dashed line at x=0.
  # Plot the 95% confidence intervals.
  geom_errorbarh(aes(xmax=upper95,xmin=lower95),
                 linewidth=0.75, height=0,color=cs) + 
  # Plot the 90% confidence intervals.
  geom_errorbarh(aes(xmax=upper90,xmin=lower90),
                 linewidth=1.5,height=0,color=cs) + 
  xlab("Estimated Effect\n(standardized)") + # Set the x-axis title.
  ylab("Bandwidth") + # Set the y-axis title.
  theme(legend.position="none", # Omit the legend.
        axis.text=element_text(size=9.3), # Set the axis text size.
        axis.title=element_text(size=14), # Set the axis title size.
        plot.title = element_text(hjust = 0.5)) + 
  xlim(-3.7,3.7) + # Set the x-axis limits.
  coord_flip() + # Flip the x and y axes.
  ggtitle("DW-NOMINATE in Subsequent Term (in Ideological Direction of Party)") + # Add a plot title.
  scale_y_continuous(breaks=seq(0.02,0.3,0.02)) # Set axis breaks.

# View the plot.
bandwidth6

# Customize the plots.
bandwidth4<-bandwidth4+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
bandwidth5<-bandwidth5+theme_classic()+theme(plot.title = element_text(hjust = 0.5))
bandwidth6<-bandwidth6+theme_classic()+theme(plot.title = element_text(hjust = 0.5))


# Combine the three plots into a single figure.
plot_grid(bandwidth4,bandwidth5,bandwidth6,ncol=1)

# Save the figure as a PDF.
ggsave("figureA9.pdf",height=5,width=5,scale=1.5)












###############################################################
##### Figure A10: Coefficient plots comparing extremist   #####
##### bare winners to moderate bare winners with rdrobust #####
###############################################################

# Make a vector with the leader traits.
leader_traits<-c("winner_female","dem",
                 "inc_winner","prim_total_winner")

# Create a data frame to store the estimates, standard deviations,
# and confidence intervals for the truncated data.
cd<-as.data.frame(matrix(0,nrow=length(leader_traits),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each leader trait.
for(i in 1:length(leader_traits)){
  
  est<-rdrobust(data_truncated[,leader_traits[i]],data_truncated$rv)[[3]][3]
  se<-rdrobust(data_truncated[,leader_traits[i]],data_truncated$rv)[[4]][3]
  
  sd_cov<-sd(data_truncated[,leader_traits[i]],na.rm=T)
  
  results<-c(est,se)
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-leader_traits

# Create a column of names for the leader traits.
cd$measure <- c("Female","Democrat",
                "Incumbent","Total Money in Primary")

# Set the order of the leader traits in the figure.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot6 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.9,2.9),breaks=seq(-2.5,2.5,by=0.5))+  
  ggtitle("Truncated Sample")

# View the coefficient plot.
plot6


# We will now make the coefficient plot for the full sample. We begin
# by creating a data frame to store the estimates, standard deviations,
# and confidence intervals for the full sample.
cd<-as.data.frame(matrix(0,nrow=length(leader_traits),ncol=7))

# Use a for loop to calculate and store the estimate, standard 
# deviation, standardized estimate, and standardized 90% and
# 95% confidence intervals for each leader trait.
for(i in 1:length(leader_traits)){
  
  est<-rdrobust(data[,leader_traits[i]],data$rv)[[3]][3]
  se<-rdrobust(data[,leader_traits[i]],data$rv)[[4]][3]
  
  sd_cov<-sd(data[,leader_traits[i]],na.rm=T)
  
  results<-c(est,se)
  
  cd[i,]<-c(results[1], sd_cov,results[1]/sd_cov, (results[1]+1.96*results[2])/sd_cov, 
            (results[1]-1.96*results[2])/sd_cov, (results[1]+1.65*results[2])/sd_cov, 
            (results[1]-1.65*results[2])/sd_cov)
  
}

# Name the columns of the data frame.
colnames(cd)<-c("estimate","sd","st_estimate",
                "upper95","lower95","upper90","lower90")

# Name the rows of the data frame.
rownames(cd)<-leader_traits

# Create a column of names for the leader traits.
cd$measure <- c("Female","Democrat",
                "Incumbent","Total Money in Primary")

# Set the order of the leader traits in the plot.
cd$ord <- c(nrow(cd):1)
cd$measure <- factor(cd$measure, levels=cd$measure[order(cd$ord)])

# Make the plot.

plot7 <- ggplot(cd, aes(x=st_estimate,y=measure,color="blue"))+
  geom_vline(xintercept=0, linetype="longdash")+
  theme_classic()+
  geom_errorbarh(aes(xmax=upper95, xmin=lower95),
                 linewidth=0.75, height=0,color="blue") +
  geom_errorbarh(aes(xmax=upper90, xmin=lower90),
                 linewidth=1.5, height=0,color="blue") +             
  geom_point(stat="identity",size=4,fill="white",color="blue")+
  xlab("Estimated Difference (Standardized)")+ylab("") +  
  theme(legend.position="none",
        axis.text.x=element_text(size=8.2),
        axis.text.y=element_text(size=9.5),
        axis.title=element_text(size=10),
        plot.title = element_text(lineheight=1.8,
                                  size=18,hjust = 0.5))+  
  scale_x_continuous(limits=c(-2.9,2.9),breaks=seq(-2.5,2.5,by=0.5)) +  
  ggtitle("Full Sample")

# View the coefficient plot.
plot7

# Combine the coefficient plots.
plot_grid(plot6,plot7,ncol=1)

# Save the resulting figure as a PDF.
ggsave("figureA10.pdf",scale=1.5,height=2.1,width=4)

